package utils
{
	import flash.display.Graphics;
	import flash.geom.Point;
	
	public class GraphicsUtils
	{
		/**
		 *  Draws an arc in the target Graphics object.  
		 *	@param	g	The Graphics object to draw into.
		 *	@param	x	The horizontal origin of the arc.
		 *	@param	y	The vertical origin of the arc.
		 *	@param	startAngle	The starting angle, in radians, of the arc.
		 *	@param	arc	The sweep, in radians, of the arc.
		 *	@param	radius  The horizontal radius, in pixels, of the arc
		 *	@param	yRadius The vertical radius, in pixels, of the arc. If unspecified, it is assumed to be the same as the radius
		 *	@param	continueFlag Indicates whether the routine should move the graphics pen to the beginning of the arc before drawing.
		 *  Set to <code>true</code> to continue drawing a line that is already in progress.
		 *  
		 *  @langversion 3.0
		 *  @playerversion Flash 9
		 *  @playerversion AIR 1.1
		 *  @productversion Flex 3
		 */
		public static function drawArc(g:Graphics, x:Number, y:Number,
									   startAngle:Number, arc:Number,
									   radius:Number, yRadius:Number = NaN,
									   continueFlag:Boolean = false):void
		{
			if (isNaN(yRadius))
				yRadius = radius;
			
			var segAngle:Number
			var theta:Number
			var angle:Number
			var angleMid:Number
			var segs:Number
			var ax:Number
			var ay:Number
			var bx:Number
			var by:Number
			var cx:Number
			var cy:Number;
			
			if (Math.abs(arc) > 2 * Math.PI)
				arc = 2 * Math.PI;
			
			segs = Math.ceil(Math.abs(arc) / (Math.PI / 4));
			segAngle = arc / segs;
			theta = -segAngle;
			angle = -startAngle;
			
			if (segs > 0)
			{
				ax = x + Math.cos(startAngle) * radius;
				ay = y + Math.sin(-startAngle) * yRadius;
				
				if (continueFlag == true)
					g.lineTo(ax, ay);
				else
					g.moveTo(ax, ay);
				
				for (var i:uint = 0; i < segs; i++)
				{
					angle += theta;
					angleMid = angle - theta / 2;
					
					bx = x + Math.cos(angle) * radius;
					by = y + Math.sin(angle) * yRadius;
					cx = x + Math.cos(angleMid) * (radius / Math.cos(theta / 2));
					cy = y + Math.sin(angleMid) * (yRadius / Math.cos(theta / 2));
					
					g.curveTo(cx, cy, bx, by);
				}
			}
		}
		
		public static function drawDashedCircle( g:Graphics, x:Number, y:Number, radius:Number, yRadius:Number = NaN ):void
		{
			var a:Number = 4;
			var b:Number = 4;
			if( radius < 20 )
			{
				a = b = 2;
			}
			var len:Number = MathUtils.PI2 * radius;
			var n:int = len / (a+b);
			b = MathUtils.PI2 / len * (a + b);
			a = MathUtils.PI2 / len * a;
			var i:int;
			var angle:Number=0;
			for( i=0; i<n; i++ )
			{
				angle = i * b;
				drawArc( g, x, y, angle, a, radius, yRadius );
			}
			
			var t:Number = Math.PI * 2 - angle - b - (b-a);
			if( t > 0 )
			{
				angle += b;
				drawArc( g, x, y, angle, t, radius, yRadius );
			}
		}
		
		public static function drawDashedLine( g:Graphics, p1:Point, p2:Point ):void     
		{
			var length:Number = 4;
			var gap:Number = 4;
			var max:Number = Point.distance(p1,p2);      
			var l:Number = 0;      
			var p3:Point;      
			var p4:Point;      
			while( l<max )      
			{      
				p3 = Point.interpolate(p2,p1,l/max);      
				l+=length;      
				if( l > max ) l=max;    
				p4 = Point.interpolate(p2,p1,l/max);      
				g.moveTo(p3.x, p3.y);
				g.lineTo(p4.x, p4.y);    
				l += gap;      
			}      
		} 
		public function GraphicsUtils()
		{
		}
	}
}